<template>
  <div class="mu-carousel">
    <div
      class="mu-carousel-container"
      ref="container"
      :style="{ height: typeof height === 'number' ? height + 'px' : height }"
    >
      <i class="mu-icon-arrow-left left" @click="switchIndex(index - 1)"></i>
      <i class="mu-icon-arrow-left right" @click="switchIndex(index + 1)"></i>
      <slot></slot>
    </div>
    <ul>
      <li
        v-on:[trigger]="switchIndex(idx)"
        :active="index === idx"
        v-for="(item, idx) in children"
        :key="idx"
      ></li>
    </ul>
  </div>
</template>

<script>
import { throttle } from "../utils/common";
export default {
  name: "mu-carousel",
  data() {
    return {
      children: [], //子元素
      index: this.initIndex, //下标
      width: 0, //宽度
    };
  },
  methods: {
    // 计算子元素宽度
    calcChildrenWidth() {
      this.width = this.$refs.container.clientWidth;
      this.children = [...this.$refs.container.children].filter((c) =>
        c.className.includes("mu-carousel-item")
      );
    },
    // 设置属性
    setAttribute(dom, { remove, name, value }) {
      if (remove) {
        dom.removeAttribute(name);
      } else {
        dom.setAttribute(name, value || "");
      }
    },
    // 设置transform
    setTransform(element, left) {
      element.style.transform = `translateX(${left}px)`;
    },
    // 初始化
    init() {
      debugger;
      const active = this.children[this.index]; //激活元素
      const left = this.children[
        this.index - 1 < 0 ? this.children.length - 1 : this.index - 1
      ];
      const right = this.children[
        this.index + 1 >= this.children.length ? 0 : this.index + 1
      ];
      this.setAttribute(active, { name: "active" });
      this.setAttribute(active, { name: "animation" });
      this.setTransform(active, 0);
      this.setTransform(left, -this.width);
      this.setTransform(right, this.width);
    },
    // 改变下标
    switchIndex(index) {
      // 改变下标总共要做三件事
      // 1: 即将要激活的元素设置z-index覆盖，并且设置动画，然后移动至旁边，然后动画移动至0
      // 2: 将上一个的激活的元素动画移动至旁边
      // 3: 重新放置左右两边的元素
      const left = index > this.index; //是否往左移动
      debugger;
      if (this.children.length < 1) {
        return;
      }
      console.log(left);
      // 如果大于最后一条则从第一条开始
      if (index > this.children.length - 1) {
        index = 0;
      } else if (index < 0) {
        // 如果小于第一条则从最后一条开始
        index = this.children.length - 1;
      }
      //即将要激活的元素
      const active = this.children[index];
      this.setAttribute(active, { name: "animation", remove: true }); //移除animation属性
      this.setTransform(active, left ? this.width : -this.width); //将元素移动至旁边，为了方便做动画
      this.setAttribute(active, { name: "active", value: "" }); //加上active属性
      this.setAttribute(active, { name: "animation", value: "" }); //加上animation属性
      this.setTransform(active, 0);
      // 将之前的激活元素移除active属性并移动至相应的位置
      const actived = this.children[this.index];
      this.setTransform(actived, left ? -this.width : this.width); //设置位置
      setTimeout(() => {
        //将之前的元素移除active和animation属性
        this.setAttribute(actived, { name: "active", remove: true });
        this.setAttribute(actived, { name: "animation", remove: true });

        // 重新放置左右两边的元素
        //左边的元素
        const leftElement = this.children.slice(index - 1)[0];
        const rightElement = this.children[
          index + 1 >= this.children.length ? 0 : index + 1
        ];
        this.setAttribute(leftElement, { name: "animation", remove: true });
        this.setAttribute(rightElement, { name: "animation", remove: true });
        this.setTransform(leftElement, -this.width);
        this.setTransform(rightElement, this.width);
      }, 500);

      this.index = index;
    },
  },
  mounted() {
    this.calcChildrenWidth();
    this.init();
  },
  props: {
    // 高度
    height: {
      type: [Number, String],
      default: "200px",
    },
    // 是否自动播放
    auto: {
      type: Boolean,
      default: true,
    },
    // 初始位置
    initIndex: {
      type: Number,
      default: 0,
    },
    // 触发方式
    trigger: {
      type: String,
      default: "mouseenter",
    },
    // 定时切换
    interval: {
      type: Number,
      default: 3000,
    },
  },
};
</script>

<style lang="scss" scoped>
.mu-carousel {
  position: relative;

  &:hover {
    .mu-carousel-container .mu-icon-arrow-left {
      opacity: 1;
      &.left {
        left: 15px;
      }

      &.right {
        right: 15px;
      }
    }
  }

  ul {
    padding: 0;
    margin: 0;
    list-style: none;
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;

    li {
      float: left;
      cursor: pointer;
      padding: 12px 4px;

      &::before {
        content: "";
        display: block;
        height: 2px;
        width: 30px;
        background: #626263;
        opacity: 0.3;
        box-sizing: border-box;
        transition: opacity 0.3s linear;
      }

      &[active] {
        &::before {
          opacity: 1;
        }
      }
    }
  }

  .mu-carousel-container {
    overflow: hidden;
    box-sizing: border-box;
    position: relative;

    .mu-icon-arrow-left {
      position: absolute;
      top: 50%;
      padding: 8px;
      line-height: 1;
      margin-top: -20px;
      z-index: 10;
      font-size: 20px;
      opacity: 0;
      border-radius: 50%;
      cursor: pointer;
      color: rgb(255, 255, 255);
      background: rgba(31, 45, 61, 0.11);
      transition: background 0.3s linear, opacity 0.3s linear, left 0.2s linear,
        right 0.2s linear;

      &:hover {
        background: rgba(31, 45, 61, 0.23);
      }

      &.left {
        left: 5px;
      }

      &.right {
        right: 5px;
        transform: rotate(180deg);
      }
    }

    .mu-carousel-item {
      height: 100%;
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
      display: inline-block;
      z-index: 0;

      &[active] {
        z-index: 2;
      }

      &[animation] {
        transition: transform 0.5s linear;
      }
    }
  }
}
</style>